
#include "Ogre\ExampleApplication.h"
/*
class CompositorListener1 : public Ogre::CompositorInstance::Listener
{
public:
	CompositorListener1() : number(125.0f) {}

	void notifyMaterialRender(uint32 pass_id, MaterialPtr &mat) {

		mat->getBestTechnique()->getPass(pass_id)->getFragmentProgramParameters()->setNamedConstant("numpixels", number);
	}

	void setNumber(float num) { number = num; }
	float getNumber() { return number; }

private:
	float number;
};*/

class CompositorListener1 : public Ogre::CompositorInstance::Listener
{
public:
	CompositorListener1(Ogre::Vector3 color) : _color(color) {}

	void notifyMaterialSetup(uint32 pass_id, MaterialPtr &mat) {

		mat->getBestTechnique()->getPass(pass_id)->getFragmentProgramParameters()->setNamedConstant("factors", _color);
	}

private:
	Ogre::Vector3 _color;
};
/*
class MyFrameListener1 : public Ogre::FrameListener
{
public:
	MyFrameListener1(RenderWindow* win, CompositorListener1* listener) : _listener(listener) {

		size_t windowHnd = 0;
		std::stringstream windowHndStr;
		win->getCustomAttribute("WINDOW", &windowHnd);
		windowHndStr << windowHnd;

		OIS::ParamList pl;
		pl.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str()));
		_man = OIS::InputManager::createInputSystem(pl);
		_key = static_cast<OIS::Keyboard*>(_man->createInputObject(OIS::OISKeyboard, false));
	}
	
	bool frameStarted(const Ogre::FrameEvent &evt) {

		_key->capture();
		if(_key->isKeyDown(OIS::KC_ESCAPE))
		{
			return false;
		}
		if(_listener) {
			if(_key->isKeyDown(OIS::KC_UP))
			{
				float num = _listener->getNumber();
				num++;
				_listener->setNumber(num);

				std::cout << num << std::endl;
			}
			if(_key->isKeyDown(OIS::KC_DOWN))
			{
				float num = _listener->getNumber();
				num--;
				_listener->setNumber(num);

				std::cout << num << std::endl;
			}
		}
		return true;
	}

private:
	OIS::InputManager* _man;
	OIS::Keyboard* _key;

	CompositorListener1* _listener;
};
*/
class Example1 : public ExampleApplication
{
public:
	Example1() {/*
		compListener = NULL;
		FrameListener = NULL;*/

		compListener[0] = NULL;
		compListener[1] = NULL;
		compListener[2] = NULL;
	}
	~Example1() {/*
		if(compListener) delete compListener;
		if(FrameListener) delete FrameListener;*/
		
		if(compListener[0]) delete compListener[0];
		if(compListener[1]) delete compListener[1];
		if(compListener[2]) delete compListener[2];
	}

	void createScene() {
	
		Ogre::SceneNode* node = mSceneMgr->getRootSceneNode()->createChildSceneNode();//"Node1", Ogre::Vector3(0, 0, 450));
		Ogre::Entity* ent = mSceneMgr->createEntity("Entity1", "Sinbad.mesh");
		//ent->setMaterialName("MyMaterial1");
		node->attachObject(ent);
		/*
		Ogre::CompositorManager::getSingleton().addCompositor(mCamera->getViewport(), "Compositor1");
		Ogre::CompositorManager::getSingleton().setCompositorEnabled(mCamera->getViewport(), "Compositor1", true);

		Ogre::CompositorInstance* comp = Ogre::CompositorManager::getSingleton().getCompositorChain(mCamera->getViewport())->getCompositor("Compositor1");

		compListener = new CompositorListener1();
		comp->addListener(compListener);*/
		
		Ogre::CompositorManager::getSingleton().addCompositor(vp, "Compositor1");
		Ogre::CompositorManager::getSingleton().setCompositorEnabled(vp, "Compositor1", true);
		Ogre::CompositorInstance* comp = Ogre::CompositorManager::getSingleton().getCompositorChain(vp)->getCompositor("Compositor1");
		compListener[0] = new CompositorListener1(Ogre::Vector3(1,0,0));
		comp->addListener(compListener[0]);

		Ogre::CompositorManager::getSingleton().addCompositor(vp2, "Compositor1");
		Ogre::CompositorManager::getSingleton().setCompositorEnabled(vp2, "Compositor1", true);
		Ogre::CompositorInstance* comp2 = Ogre::CompositorManager::getSingleton().getCompositorChain(vp2)->getCompositor("Compositor1");
		compListener[1] = new CompositorListener1(Ogre::Vector3(0,1,0));
		comp2->addListener(compListener[1]);

		Ogre::CompositorManager::getSingleton().addCompositor(vp3, "Compositor1");
		Ogre::CompositorManager::getSingleton().setCompositorEnabled(vp3, "Compositor1", true);
		Ogre::CompositorInstance* comp3 = Ogre::CompositorManager::getSingleton().getCompositorChain(vp3)->getCompositor("Compositor1");
		compListener[2] = new CompositorListener1(Ogre::Vector3(0,0,1));
		comp3->addListener(compListener[2]);
	}
	/*
	void createFrameListener() {

		FrameListener = new MyFrameListener1(mWindow, compListener);
		mRoot->addFrameListener(FrameListener);
	}*/

	void createCamera() {

		mCamera = mSceneMgr->createCamera("MyCamera1");
		mCamera->setPosition(0, 10, 20);
		mCamera->lookAt(0, 0, 0);
		mCamera->setNearClipDistance(5);
		/*
		mCamera3 = mSceneMgr->createCamera("MyCamera3");
		mCamera3->setPosition(0, 10, -20);
		mCamera3->lookAt(0, 0, 0);
		mCamera3->setNearClipDistance(5);

		mCamera4 = mSceneMgr->createCamera("MyCamera4");
		mCamera4->setPosition(-20, 10, 0);
		mCamera4->lookAt(0, 0, 0);
		mCamera4->setNearClipDistance(5);

		mCamera2 = mSceneMgr->createCamera("MyCamera2");
		mCamera2->setPosition(20, 10, 0);
		mCamera2->lookAt(0, 0, 0);
		mCamera2->setNearClipDistance(5);*/
	}

	void createViewports() {
		/*
		Ogre::Viewport* vp = mWindow->addViewport(mCamera, 0, 0.0, 0.0, 0.5, 0.5);
		vp->setBackgroundColour(ColourValue(0.0f, 0.0f, 0.0f));
		
		Ogre::Viewport* vp3 = mWindow->addViewport(mCamera3, 2, 0.5, 0.0, 0.5, 0.5);
		vp3->setBackgroundColour(ColourValue(0.0f, 0.0f, 0.0f));

		Ogre::Viewport* vp4 = mWindow->addViewport(mCamera4, 3, 0.0, 0.5, 0.5, 0.5);
		vp4->setBackgroundColour(ColourValue(0.0f, 0.0f, 0.0f));

		Ogre::Viewport* vp2 = mWindow->addViewport(mCamera2, 1, 0.5, 0.5, 0.5, 0.5);
		vp2->setBackgroundColour(ColourValue(0.0f, 0.0f, 0.0f));

		mCamera->setAspectRatio(Real(vp->getActualWidth()) / Real(vp->getActualHeight()));
		mCamera3->setAspectRatio(Real(vp3->getActualWidth()) / Real(vp3->getActualHeight()));
		mCamera4->setAspectRatio(Real(vp4->getActualWidth()) / Real(vp4->getActualHeight()));
		mCamera2->setAspectRatio(Real(vp2->getActualWidth()) / Real(vp2->getActualHeight()));*/

		vp = mWindow->addViewport(mCamera, 0, 0.0, 0.0, 0.5, 0.5);
		vp->setBackgroundColour(ColourValue(0.0f, 0.0f, 0.0f));

		vp2 = mWindow->addViewport(mCamera, 1, 0.5, 0.0, 0.5, 0.5);
		vp2->setBackgroundColour(ColourValue(0.0f, 0.0f, 0.0f));

		vp3 = mWindow->addViewport(mCamera, 2, 0.0, 0.5, 0.5, 0.5);
		vp3->setBackgroundColour(ColourValue(0.0f, 0.0f, 0.0f));

		vp4 = mWindow->addViewport(mCamera, 3, 0.5, 0.5, 0.5, 0.5);
		vp4->setBackgroundColour(ColourValue(0.0f, 0.0f, 0.0f));

		mCamera->setAspectRatio(Real(vp->getActualWidth()) / Real(vp->getActualHeight()));
	}

private:
	//CompositorListener1* compListener;

	//Ogre::FrameListener* FrameListener;
	/*
	Ogre::Camera* mCamera2;
	Ogre::Camera* mCamera3;
	Ogre::Camera* mCamera4;
	*/
	Ogre::Viewport* vp;
	Ogre::Viewport* vp2;
	Ogre::Viewport* vp3;
	Ogre::Viewport* vp4;

	CompositorListener1* compListener[3];
};

int main(void) {

	Example1 app;
	app.go();

	return 0;
}